package com.lagou.springexp;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;

/**
 * @ClassName ServiceScannerRegistrar
 * @Description
 * @Author playboy
 * @Date 2021/6/5 5:15 下午
 * @Version 1.0
 **/
public class ServiceScannerRegistrar implements ImportBeanDefinitionRegistrar {
	private static Logger log = LoggerFactory.getLogger(ServiceScannerRegistrar.class);


	/**
	 * 获取@EnableRpcService注解上添加的要扫描的接口的路径
	 *
	 * @param importingClassMetadata
	 * @param registry
	 */
	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		AnnotationAttributes mapperScanAttrs = AnnotationAttributes
				.fromMap(importingClassMetadata.getAnnotationAttributes(EnableRpcService.class.getName()));
		if (mapperScanAttrs != null) {
			registerBeanDefinitions(mapperScanAttrs, registry, generateBaseBeanName(importingClassMetadata, 0));
		}
	}

	/**
	 * 生成一个ServiceScannerConfigurer的beanDefinition，并且注入到spring的BeanDefinitionRegistry中
	 * 作用：ServiceScannerConfigurer实现了BeanDefinitionRegistryPostProcessor，所以在Spring启动的过程中会调用
	 * postProcessBeanDefinitionRegistry接口，将我们想要扫描的接口注入到BeanDefinitionRegistry中
	 *
	 * @param annoAttrs
	 * @param registry
	 * @param beanName
	 */
	void registerBeanDefinitions(AnnotationAttributes annoAttrs, BeanDefinitionRegistry registry, String beanName) {

		BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(ServiceScannerConfigurer.class);

		builder.addPropertyValue("serviceFactoryBeanClass", ServiceFactoryBean.class);

		builder.addPropertyValue("basePackage", annoAttrs.getStringArray("basePackage"));

		registry.registerBeanDefinition(beanName, builder.getBeanDefinition());

	}


	private static String generateBaseBeanName(AnnotationMetadata importingClassMetadata, int index) {
		return importingClassMetadata.getClassName() + "#" + ServiceScannerRegistrar.class.getSimpleName() + "#" + index;
	}
}
